package com.linkoog.devtools.code_generator.wizard.model.ddl;

import com.linkoog.devtools.code_generator.database.domain.ColumnInfo;
import com.linkoog.devtools.code_generator.database.domain.DbType;
import com.linkoog.devtools.code_generator.database.domain.TableInfo;
import com.linkoog.devtools.code_generator.util.FileTypeUtil;
import com.linkoog.devtools.code_generator.util.StringUtil;
import com.linkoog.devtools.code_generator.wizard.generate.database.table.dialog.datasource.panel.DbTypeComboBoxCellRender;
import com.linkoog.devtools.intellij.wizard.WizardContext;
import com.linkoog.devtools.intellij.wizard.WizardStep;
import com.linkoog.devtools.code_generator.wizard.ModelWizardContext;
import com.linkoog.devtools.code_generator.database.sqlparser.ParseResult;
import com.linkoog.devtools.code_generator.database.sqlparser.ParseState;
import com.linkoog.devtools.code_generator.database.sqlparser.parser.SqlParser;
import com.linkoog.devtools.code_generator.database.sqlparser.parser.SqlParserFactory;
import com.linkoog.devtools.code_generator.common.JavaType;
import com.linkoog.devtools.code_generator.wizard.model.ModelJsonTreeTable;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import javax.swing.*;
import java.awt.*;
import java.util.List;


public class ModelDDLStep extends WizardStep {

    private JPanel myMainPanel;
    private JComboBox dbTypeComboBox;
    private JScrollPane sqlTextScrollPane;

    private Editor sqlTextEditor;

    public ModelDDLStep(Project project, WizardContext wizardContext) {
        super(project, wizardContext);
        myMainPanel.setMinimumSize(new Dimension(770, 550));

        dbTypeComboBox.setRenderer(new DbTypeComboBoxCellRender());
        for (DbType dbType : DbType.values()) {
            dbTypeComboBox.addItem(dbType);
        }

        // 设置 sql text editor
        EditorFactory editorFactory = EditorFactory.getInstance();
        Document document = editorFactory.createDocument("");
        sqlTextEditor = editorFactory.createEditor(document, project, FileTypeUtil.getFileType("SQL"), false);

        sqlTextScrollPane.setViewportView(sqlTextEditor.getComponent());
    }

    public JPanel getMyMainPanel() {
        return myMainPanel;
    }

    public String getCreateTableSql() {
        return sqlTextEditor.getDocument().getText();
    }

    @Override
    public boolean validate() throws ConfigurationException {
        String ddlSql = getCreateTableSql();
        if (StringUtils.isBlank(ddlSql)) {
            throw new ConfigurationException("请输入建表语句！", "错误");
        }

        ddlSql = handlerDDLSql(ddlSql);
        ParseResult parseResult = getParseResult(ddlSql);
        if (ParseState.SUCCESS != parseResult.getParseState()) {
            throw new ConfigurationException("ddl语句解析失败：" + parseResult.getErrorMessage(), "错误");
        } else {
            List<TableInfo> tableInfoList = parseResult.getTableInfos();
            if (tableInfoList.size() == 0) {
                throw new ConfigurationException("未解析到建表语句！", "错误");
            } else if (tableInfoList.size() > 1){
                throw new ConfigurationException("解析到多个建表语句！", "错误");
            }

            TableInfo info = tableInfoList.get(0);
            ModelWizardContext modelWizardContext = (ModelWizardContext) getWizardContext();
            modelWizardContext.setClassName(info.getJavaEntityName());
            modelWizardContext.setClassRemark(info.getTableComment());

            ModelJsonTreeTable.ItemInfo rootNode = ModelJsonTreeTable.createRootNode();
            rootNode.setRemark(info.getTableComment());
            for (ColumnInfo columnInfo : info.getColumnInfos()) {
                ModelJsonTreeTable.ItemInfo field = new ModelJsonTreeTable.ItemInfo();
                field.setName(columnInfo.getJavaFieldName());
                field.setNameEditable(true);
                field.setChecked(true);
                field.setCheckEditable(true);
                JavaType javaType = JavaType.valueOfName(columnInfo.getJavaFieldType());
                field.setType(javaType==null? JavaType.STRING: javaType);
                field.setRemark(columnInfo.getColumnComment());

                rootNode.add(field);
            }
            modelWizardContext.setRoot(rootNode);
        }

        return true;
    }

    private String handlerDDLSql(String ddlSql){
        if (StringUtil.isBlank(ddlSql)){
            return ddlSql;
        }

        DbType dbType = getDbType();
        if (DbType.POSTGRE == dbType){
            return ddlSql.replaceAll("\"public\".\"geometry\"", "varchar(255)");
        }
        return ddlSql;
    }


    @Override
    public void onStepOK() {
    }

    private ParseResult getParseResult(String ddlSql) {
        DbType dbType = getDbType();
        SqlParser sqlParser = SqlParserFactory.createSqlParser(dbType);
        ParseResult parseResult = sqlParser.parseCreateTable(ddlSql);
        return parseResult;
    }

    private DbType getDbType(){
        return (DbType) dbTypeComboBox.getSelectedItem();
    }

    @Override
    public JPanel getComponent() {
        return myMainPanel;
    }


    private void createUIComponents() {
        // TODO: place custom component creation code here
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        myMainPanel = new JPanel();
        myMainPanel.setLayout(new GridLayoutManager(2, 2, new Insets(0, 0, 0, 0), -1, -1));
        final JLabel label1 = new JLabel();
        label1.setText("数据库");
        myMainPanel.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        dbTypeComboBox = new JComboBox();
        myMainPanel.add(dbTypeComboBox, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        sqlTextScrollPane = new JScrollPane();
        myMainPanel.add(sqlTextScrollPane, new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return myMainPanel;
    }


}
